package com.google.code.drift.activity;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alibaba.fastjson.JSONObject;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MapView.LayoutParams;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.google.code.drift.R;
import com.google.code.drift.api.AppSkyApp;
import com.google.code.drift.api.Refreshable;
import com.google.code.drift.api.UserInfo;
import com.google.code.drift.utils.AlertUtils;
import com.google.code.drift.utils.DLog;
import com.google.code.drift.utils.JsonFactory;
import com.google.code.drift.utils.CommonUtils;

public class MapChatActivity extends MapActivity implements Refreshable {

	private MapView mainMap;

	private AppSkyApp app;

	private RelativeLayout functionBubbleLayout;

	private Button createRoomButton;

	private AlertUtils alert;

	private boolean isRegistReceiver = false;

	private Map<Integer, View> popToUser = new HashMap<Integer, View>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.map_tab_layout);

		DLog.i("MapChatActivity onCreate");

		app = (AppSkyApp) getApplication();
		alert = new AlertUtils(this);
		initView();
		initMapView();
	}

	@Override
	protected void onResume() {
		DLog.i("MapChatActivity onResume");
		if (!isRegistReceiver) {
			IntentFilter filter = new IntentFilter(
					CommonUtils.ACTION_CHAT_MESSAGE_RECEIVER);
			isRegistReceiver = true;
			registerReceiver(chatMessageReceiver, filter);
		}
		if (app.isLocationChange()) {
			initMapView();
		}
		super.onResume();
	}

	@Override
	protected void onDestroy() {
		if (isRegistReceiver) {
			unregisterReceiver(chatMessageReceiver);
			isRegistReceiver = false;
			chatMessageReceiver = null;
		}
		if (alert != null) {
			alert.release();
			alert = null;
		}
		if (mainMap != null) {
			mainMap = null;
		}
		if (popToUser != null) {
			popToUser.clear();
			popToUser = null;
		}
		super.onDestroy();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public void refresh() {
		initMapView();
	}

	private void initView() {
		initButtons();
		initFunctionBubble();
	}

	private void initButtons() {
		// createRoomButton = (Button) findViewById(R.id.create_room);
		// createRoomButton.setOnClickListener(new OnClickListener() {
		// @Override
		// public void onClick(View v) {
		// JsonFactory jsonFactory = JsonFactory.getFactory();
		// JSONObject json = jsonFactory.makeCreateRoomJson(app
		// .getMyInfo().getUserId());
		// CommonUtils.sendDataToServer(MapChatActivity.this,
		// json.toJSONString());
		// app.getMyInfo().setRoomId(app.getMyInfo().getUserId());
		// Intent activityIntent = new Intent(MapChatActivity.this,
		// ChatMainActivity.class);
		// startActivity(activityIntent);
		// }
		// });
	}

	private void initFunctionBubble() {
		functionBubbleLayout = (RelativeLayout) getLayoutInflater().inflate(
				R.layout.function_bubble_layout, null);
		TextView userInfoButton = (TextView) functionBubbleLayout
				.findViewById(R.id.function_user_info);
		userInfoButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {

			}
		});
		TextView joinButton = (TextView) functionBubbleLayout
				.findViewById(R.id.function_join_room);
		joinButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				UserInfo user = (UserInfo) functionBubbleLayout.getTag();
				DLog.i(user.getNick() + " 的功能键被点击");
			}
		});
	}

	/**
	 * 可以用来刷新地图
	 */
	private void initMapView() {
		DLog.i("刷新地图！！");
		if (mainMap == null) {
			mainMap = (MapView) findViewById(R.id.main_map);
			mainMap.setSatellite(false);
			mainMap.setTraffic(false);
			mainMap.setStreetView(false);
		}

		setMapView();
		initBubbleView();
		initChatBubbleView();

	}

	private void initChatBubbleView() {
		Collection<UserInfo> userList = app.getMyInfo()
				.getNearbyPersonListFromHashMap();
		Iterator<UserInfo> iterator = userList.iterator();
		while (iterator.hasNext()) {
			addChatBubbleView(iterator.next());
		}
		addChatBubbleView(app.getMyInfo());// 这里别忘把自己添加进去
	}

	private void addChatBubbleView(UserInfo user) {
		TextView popView = new TextView(this);
		popView.setGravity(Gravity.CENTER_HORIZONTAL);
		if (user.getUserId() == app.getMyInfo().getUserId()) {
			popView.setBackgroundResource(R.drawable.pop_chat);
		} else {
			popView.setBackgroundResource(R.drawable.other_pop_chat);
		}
		popView.setMaxWidth(getWindowManager().getDefaultDisplay().getWidth() / 2);
		GeoPoint geo = new GeoPoint((user.getLatitude()), (user.getLongitude()));
		LayoutParams lp = new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT, geo,
				MapView.LayoutParams.BOTTOM_CENTER);
		mainMap.addView(popView, lp);
		popView.setVisibility(View.INVISIBLE);
		popToUser.put(user.getUserId(), popView);
		DLog.i("被添加到popToUser里的用户的ID：" + user.getUserId());
	}

	private void setMapView() {

		GeoPoint point = new GeoPoint(app.getMyInfo().getLatitude(), app
				.getMyInfo().getLongitude());
		List<Overlay> mapOverlays = mainMap.getOverlays();
		mapOverlays.clear();
		MyPlaceOverlay myPlace = new MyPlaceOverlay(point);
		mapOverlays.add(myPlace);

		MapController mapController = mainMap.getController();
		mapController.animateTo(point);
		mapController.setZoom(9);

	}

	private void initBubbleView() {
		mainMap.removeAllViews();
		Collection<UserInfo> userList = app.getMyInfo()
				.getNearbyPersonListFromHashMap();
		Iterator<UserInfo> iterator = userList.iterator();
		while (iterator.hasNext()) {
			addUserBubbleView(iterator.next());
		}
		// XXX 测试用！
//		addUserBubbleView(app.getMyInfo());
	}

	private void addUserBubbleView(final UserInfo user) {
		RelativeLayout bubbleView = (RelativeLayout) getLayoutInflater()
				.inflate(R.layout.user_bubble_layout, null);
		TextView textView = (TextView) bubbleView
				.findViewById(R.id.user_bubble_nick);
		textView.setText(user.getNick());
		// XXX 这个是新版本中的功能
		// bubbleView.setOnClickListener(new OnClickListener() {
		// @Override
		// public void onClick(View v) {
		// showBubble(user);
		// }
		// });
		GeoPoint geo = new GeoPoint(user.getLatitude(), user.getLongitude());
		LayoutParams lp = new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT, geo,
				MapView.LayoutParams.CENTER_HORIZONTAL);
		mainMap.addView(bubbleView, lp);
	}

	private void showBubble(UserInfo user) {
		GeoPoint geo = animateToAndCreatGeo(user);
		setBubbleLayout(user);
		addToMapView(geo);
	}

	/**
	 * 移动到geo这个点上，并把这个geo返回
	 * 
	 * @param user
	 *            user里存放着坐标，用来生成geo
	 * @return
	 */
	private GeoPoint animateToAndCreatGeo(UserInfo user) {
		MapController controller = mainMap.getController();
		GeoPoint geo = new GeoPoint(user.getLatitude(),
				user.getLongitude() + 10);
		controller.animateTo(geo);
		return geo;
	}

	private void setBubbleLayout(UserInfo user) {
		functionBubbleLayout.setTag(user);
		ImageView avatar = (ImageView) functionBubbleLayout
				.findViewById(R.id.function_bubble_avatar);
		TextView nick = (TextView) functionBubbleLayout
				.findViewById(R.id.function_bubble_nick);
		ImageView sex = (ImageView) functionBubbleLayout
				.findViewById(R.id.function_bubble_sex);
		avatar.setImageResource(R.drawable.a_avatar);
		nick.setText(user.getNick());
		if (user.getSex() == 0) {
			sex.setImageResource(R.drawable.female);
		} else if (user.getSex() == 1) {
			sex.setImageResource(R.drawable.male);
		} else {
			sex.setImageResource(R.drawable.secrecy);
		}
	}

	/**
	 * 把这个functionBubble添加到mainMap
	 * 
	 * @param geo
	 *            MapView.LayoutParams需要
	 */
	private void addToMapView(GeoPoint geo) {
		LayoutParams lp = new MapView.LayoutParams(
				MapView.LayoutParams.WRAP_CONTENT,
				MapView.LayoutParams.WRAP_CONTENT, geo,
				MapView.LayoutParams.BOTTOM_CENTER);
		mainMap.removeView(functionBubbleLayout);
		mainMap.addView(functionBubbleLayout, lp);
	}

	private class MyPlaceOverlay extends Overlay {

		private GeoPoint geoPoint = null;

		public MyPlaceOverlay(GeoPoint geoPoint) {
			this.geoPoint = geoPoint;
		}

		@Override
		public boolean onTap(GeoPoint p, MapView mapView) {
			mainMap.removeView(functionBubbleLayout);
			return super.onTap(p, mapView);
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			Point point = new Point();
			Projection projection = mapView.getProjection();
			projection.toPixels(geoPoint, point);
			Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
					R.drawable.my_place);
			canvas.drawBitmap(bitmap, point.x, point.y, null);
		}

	}

	private BroadcastReceiver chatMessageReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			DLog.i("MapMod收到聊天消息");
			String string = intent.getStringExtra("json");
			int id = inflatChatBubble(string);

			// 如果不是自己发的，就触发提示
			if (app.getMyInfo().getUserId() != id) {
				alert.alert();
			}
		}
	};

	private int inflatChatBubble(String jsonString) {
		JSONObject json = JSONObject.parseObject(jsonString);
		int id = json.getIntValue("id");
		DLog.i("说话的人的ID：" + id);
		String content = json.getString("content");
		TextView bubble = (TextView) popToUser.get(id);
		bubble.setVisibility(View.VISIBLE);
		bubble.setText(content);
		return id;
	}
}